#include "tinyxml.h"
#include "stdafx.h"
#include "collada.h"

#ifdef _DEBUG
#define DEBUG_NEW new( _NORMAL_BLOCK, __FILE__, __LINE__ )
#define new DEBUG_NEW
#endif

using namespace Collada;

IMPLEMENT_RTTI( Collada::Source, Collada::Element )
IMPLEMENT_ELEMENT( Collada::Source )

Source::Source( const std::string& id, const std::string& name )
:	Element( id, name )
,	_array( NULL )
,	_arraySize( 0 )
,	_count( 0 )
,	_typeAndFormat( 0 )
,	_sourceID( 0 )
,	_stride( 0 )
{
	CHILD_ELEMENT_BEGIN()
		CHILD_ELEMENT( "asset", Collada::Empty )
		CHILD_ELEMENT( "bool_array", Collada::Empty )
		CHILD_ELEMENT( "float_array", Collada::Empty )
		CHILD_ELEMENT( "IDREF_array", Collada::Empty )
		CHILD_ELEMENT( "int_array", Collada::Empty )
		CHILD_ELEMENT( "Name_array", Collada::Empty )
		CHILD_ELEMENT( "SIDREF_array", Collada::Empty )
		CHILD_ELEMENT( "token_array", Collada::Empty )
		CHILD_ELEMENT( "technique_common", Collada::Empty )
		CHILD_ELEMENT( "techniuqe", Collada::Empty )
	CHILD_ELEMENT_END()
}

Source::~Source()
{
	if( _array )
	{
		delete[] _array;
		_array = NULL;
	}
}

void Source::AllChildElementsLoaded( Element* pParent )
{
}

bool Source::GetArrayData( char* pStream )
{
	bool*	pBoolArray		= NULL;
	float*	pFloatArray		= NULL;
	int*	pIntArray		= NULL;
	
	if( _arrayType == "bool_array" )
	{
	}
	if( _arrayType == "float_array" )
	{
		pFloatArray = new float[ _arraySize ];
		_array = ( void* )pFloatArray;
	}
	if( _arrayType == "int_array" )
	{
		pIntArray = new int[ _arraySize ];
		_array = ( void* )pIntArray;
	}

	for( int i = 0; i < _arraySize; ++i )
	{
		if( pBoolArray )
		{
		}
		if( pFloatArray )
		{
			sscanf_s( pStream, "%f", &pFloatArray[i] );
		}
		if( pIntArray )
		{
			sscanf_s( pStream, "%d", &pIntArray[i] );
		}
		strtok_s( pStream, " ", &pStream );
	}

	return true;
}

void Source::Initialize( Element* pParent, const void* desc )
{
	TiXmlElement* pElem = ( TiXmlElement* )desc;
	const char* srcIdStr = pElem->Attribute( "id" );
	if( srcIdStr != NULL )
	{
		_sourceID = Fundamental::JenkinsPHF( srcIdStr );
	}

	// Skip if it's asset.
	TiXmlElement* pChild = pElem->FirstChildElement();
	if( std::string( pChild->Value() ) == "asset" )
	{
		pChild = pChild->NextSiblingElement();
	}

	// Should be one of the array elements or not
	std::string arrayName = pChild->Value();
	if( arrayName != "technique_common" ||
		arrayName != "technique" )
	{
		_arrayType = std::string( pChild->Value() );
		_arraySize = atoi( pChild->Attribute( "count" ) );
		char* stream = const_cast< char* >( pChild->GetText() );
		GetArrayData( stream );
	}

	// technique_common
	pChild = pElem->FirstChildElement( "technique_common" );
	if( pChild != NULL )
	{
		TiXmlElement* pAccessor = pChild->FirstChildElement( "accessor" );
		const char* count	= pAccessor->Attribute( "count" );
		const char* stride	= pAccessor->Attribute( "stride" );

		_count = atoi( count );
		_stride = ( stride )? atoi( stride ) : 1;

		std::vector< const char > byte;
		TiXmlElement* pParam = pAccessor->FirstChildElement();
		Type type = StrToType( pParam->Attribute( "type" ) );
		for( ; pParam; pParam = pParam->NextSiblingElement() )
		{
			std::string name( pParam->Attribute( "name" ) );
			byte.push_back( name.c_str()[0] - 'X' + 1 );
		}

		size_t size = byte.size();
		for( size_t i = size; i < 4; ++i )
		{
			byte.push_back( 0 );
		}
		Format format = SetFormat( byte[0], byte[1], byte[2], byte[3] );
		_typeAndFormat = type | ( size << 16 ) | format;
	}

	// technique
	pChild = pElem->FirstChildElement( "technique" );
	if( pChild != NULL )
	{
	}

	// If parent is convex_mesh
	// If parent is mesh
	if( pParent->IsA( Mesh::GetTypeInfo() ) )
	{
		( ( Mesh* )pParent )->AddSource( this );
		return;
	}
	// If parent is splash
	// If parent is brep
	
}

bool Source::IsValid( const void* desc )
{
	return true;
}